package com.jule.robot.strategy.impl;

import JoloProtobuf.GameSvr.JoloGame;
import com.jule.core.service.CronTaskManager;
import com.jule.core.service.ThreadPoolManager;
import com.jule.robot.model.PlayerInfo;
import com.jule.robot.model.eenum.PlayerStateEnum;
import com.jule.robot.service.holder.FunctionIdHolder;
import com.jule.robot.service.websocket.BaseWebSocketClient;
import com.jule.robot.strategy.BaseRobotStrategry;
import com.jule.robot.util.RandomTools;
import com.jule.robot.valve.gate.RobotThreadPoolManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import java.util.function.Consumer;

public class SideShowStateStrategry extends BaseRobotStrategry {
    private final static Logger logger = LoggerFactory.getLogger(SideShowStateStrategry.class);
    public SideShowStateStrategry() {
    }

    @Override
    public void doAction(BaseWebSocketClient client, int functionId, byte[] bytes) {
//        setClient(client);
        try {
            JoloGame.JoloGame_GetSideShowStateAck ack = JoloGame.JoloGame_GetSideShowStateAck.parseFrom(bytes);
            StringBuilder logStr = new StringBuilder();
            logStr.append("Ack_GetSideShowState Header, functionId->"+functionId+", functionName->"+ FunctionIdHolder.GetFunctionName(functionId)+", ACK Body, result->" + ack.getResult() + ", ResultMsg->" + ack.getResultMsg()
                    + ", userId->"+ack.getUserId()+", roomId->"+ack.getRoomId() +", tableId->"+ack.getTableId()+", gameOrderId->"+ack.getGameOrderId()+", betScore->"+ack.getBetScore()+", getCanChooseTargetUserListCount->{}"+ack.getCanChooseTargetUserListCount());
            if(ack.getResult() == 1 && ack.getIsCanChooseTargetUser() == 1){
                for(JoloGame.JoloGame_TablePlay_PlayerSeatInfo playerInfo : ack.getCanChooseTargetUserListList()){
                    logStr.append(", CanChooseUser userId->"+playerInfo.getUserId()+", seatNum->"+playerInfo.getSeatNum());
                }

                int canChooseUserCnt = ack.getCanChooseTargetUserListCount();
                JoloGame.JoloGame_TablePlay_PlayerSeatInfo playerInfo = ack.getCanChooseTargetUserListList().get( (RandomTools.getRandomNum(canChooseUserCnt))-1 );
                logger.info("允许选择SideShow用户，随机选择sideShow用户为->"+playerInfo.getUserId()+", seatNum->"+playerInfo.getSeatNum());
                ExecuteApplyChooseUser(client, playerInfo.getUserId());
            }else{
                PlayerInfo robotInfo = client.getOnTablePlayers().get(client.getUserId());
                if(null != robotInfo){
                    PlayerInfo prePlayerInfo = getPreBetPlayer(client, robotInfo.getSeatNum());
                    logger.info("禁止选择SideShow用户，与上家比牌， 上家userId->"+prePlayerInfo.getUserId()+", seatNum->"+prePlayerInfo.getSeatNum());
                    ExecuteApplySideShow(client, prePlayerInfo.getUserId(), ack.getBetScore());
                }
            }
            logger.info(logStr.toString());
        }catch (Exception ex){
            logger.error("Ack_GetSideShowState error, functionId->{}, gameId->{}, roomId->{}, tableId->{}, userId->{}, msg->{}",
                    functionId, client.getGameId(), client.getRoomId(), client.getTableId(), client.getUserId(), ex.getMessage(), ex);
        }
    }

    /**
     * 选择被比牌用户
     * @param targetUserId
     */
    public void ExecuteApplyChooseUser(BaseWebSocketClient client, String targetUserId){
        JoloGame.JoloGame_ApplyChooseUserReq.Builder req =  JoloGame.JoloGame_ApplyChooseUserReq.newBuilder();
        req.setUserId(client.getUserId());
        req.setRoomId(client.getRoomId());
        req.setTableId(client.getTableId());
        req.setGameOrderId(client.getGameOrderId());
        req.setTargetUserId(targetUserId);

        int reqNum = (int)(System.currentTimeMillis()/1000);
        int functionId = FunctionIdHolder.Game_REQ_ApplyChooseUser;

        logger.info("GameReq_ApplyChooseUser Body, reqNum->"+reqNum+", functionName->"+FunctionIdHolder.GetFunctionName(functionId)+", userId->" + req.getUserId() + ", roomId->" + req.getRoomId() + ", tableId->"+req.getTableId()
                +", gameOrderId->"+req.getGameOrderId()+", targetUserId->"+targetUserId);

        long delayMillSec = (long)((RandomTools.getRandomNum(3)) * 1000);
        Timer timer=new Timer();//实例化Timer类
        timer.schedule(new TimerTask(){
            public void run(){
                client.sendData(functionId, client.getGameId(), reqNum, req.build().toByteArray(), client.getGameSvrId());
            }}, delayMillSec+1000);
    }

    /**
     * 执行sideShow操作
     * @param targetUserId
     * @param betScore
     */
    public void ExecuteApplySideShow(BaseWebSocketClient client, String targetUserId, double betScore){
        JoloGame.JoloGame_ApplySideShowReq.Builder req =  JoloGame.JoloGame_ApplySideShowReq.newBuilder();
        req.setUserId(client.getUserId());
        req.setRoomId(client.getRoomId());
        req.setTableId(client.getTableId());
        req.setGameOrderId(client.getGameOrderId());
        req.setTargetUserId(targetUserId);
        req.setBetScore(betScore);

        int reqNum = (int)(System.currentTimeMillis()/1000);
        int functionId = FunctionIdHolder.Game_REQ_ApplySideShow;

        logger.info("GameReq_ApplySideShow Body, reqNum->"+reqNum+", functionName->"+FunctionIdHolder.GetFunctionName(functionId)+", userId->" + req.getUserId() + ", roomId->" + req.getRoomId() + ", tableId->"+req.getTableId()
                +", gameOrderId->"+req.getGameOrderId()+", targetUserId->"+targetUserId);

        //延迟但3-8秒内进行
//        Consumer<Object> call = obj -> {
//            RobotThreadPoolManager.getInstance().addTask(new Runnable() {
//                @Override
//                public void run() {
//                    client.sendData(functionId, client.getGameId(), reqNum, req.build().toByteArray(), client.getGameSvrId());
//                }
//            });
//        };
//        long t = new Date().getTime() + (long)((client.getRandomNum(3)+2) * 1000);
//        CronTaskManager.CountDownTask task = new CronTaskManager.CountDownTask(t, call);
//        CronTaskManager.getInstance().addCountDownJob(task.getName(), "SIDESHOW", task);

        long delayMillSec = (long)((RandomTools.getRandomNum(3)+2) * 1000);
        Timer timer=new Timer();//实例化Timer类
        timer.schedule(new TimerTask(){
            public void run(){
                client.sendData(functionId, client.getGameId(), reqNum, req.build().toByteArray(), client.getGameSvrId());
            }}, delayMillSec);
    }

    /**
     * 获得上一个行动的玩家
     * @param nextBetSeatNum
     * @return
     */
    public PlayerInfo getPreBetPlayer(BaseWebSocketClient client, int nextBetSeatNum){
        PlayerInfo preBetPlayer = null;

        //计算下一个下注玩家的座位号
        int preBetSeatNum = nextBetSeatNum;
        while(true){
            preBetSeatNum -= 1;
            if(preBetSeatNum < 1){
                preBetSeatNum = 5;
            }
            //再次找到当前位置，说明已无合适上一个行动者，返回null
            if(nextBetSeatNum == preBetSeatNum){
                return null;
            }
            logger.debug("桌上有几个人==============================："+client.getOnTablePlayers().size()+
                    ",inGamePlayer:"+client.getInGamePlayersBySeatNum()+",preBetSeatNum:"+preBetSeatNum);
            if(client.getInGamePlayersBySeatNum().containsKey(preBetSeatNum)){
                logger.debug("上一个玩家的座位=================================："+preBetSeatNum);
                preBetPlayer = client.getInGamePlayersBySeatNum().get(preBetSeatNum);
                if(preBetPlayer.getState() != PlayerStateEnum.fold.getValue()){
                    //跳出while循环
                    break;
                }

            }
        }
        return preBetPlayer;
    }
}
